#include "widget.h"
#include "ui_widget.h"
#include <QTcpSocket>
#include <QFile>
#include <QDataStream>
#include <QFileDialog>
#include <QDebug>
#include <QMessageBox>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    model = new QStandardItemModel(this);
    ui->tableView->setModel(model);
    model->setHorizontalHeaderLabels({"文件名"});

    // 在窗口显示时自动请求文件列表
    requestFileList("127.0.0.1", 12345);

    connect(ui->uploadBtn, &QPushButton::clicked, this, &Widget::uploadFile);
    connect(ui->dowmloadBtn, &QPushButton::clicked, this, &Widget::downloadFile);
    connect(ui->selectBtn, &QPushButton::clicked, this, &Widget::selectFile);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::selectFile() {
    QString filePath = QFileDialog::getOpenFileName(this, "Select file to upload");
    if (!filePath.isEmpty()) {
        ui->textEdit->setText(filePath);  // 在 textEdit 中显示选中的文件路径
    }
}

void Widget::uploadFile() {
    QString filePath = ui->textEdit->toPlainText();
    if (!filePath.isEmpty()) {
        uploadFileToServer("127.0.0.1", 12345, filePath);
        // 上传完成后刷新文件列表
        requestFileList("127.0.0.1", 12345);
        QMessageBox::information(this, "上传成功", "文件上传成功！");  // 上传完成后给出提示
    }
}

void Widget::downloadFile() {
    QModelIndexList selectedRows = ui->tableView->selectionModel()->selectedRows();
    if (!selectedRows.isEmpty()) {
        QString fileName = selectedRows.first().data().toString();
        QString savePath = QFileDialog::getExistingDirectory(this, "Select directory to save downloaded file");
        if (!savePath.isEmpty()) {
            downloadFileFromServer("127.0.0.1", 12345, fileName, savePath);
        }
    }
}

void Widget::uploadFileToServer(const QString &serverAddress, quint16 serverPort, const QString &filePath) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {  // 如果文件无法打开，输出错误信息
        qDebug() << "Unable to open file for reading";
        return;
    }

    QTcpSocket socket;
    socket.connectToHost(serverAddress, serverPort);  // 连接到服务器
    if (socket.waitForConnected()) {  // 等待连接成功
        QByteArray request;
        QDataStream out(&request, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_5_12);
        out << QString("UPLOAD") << file.fileName() << file.size();  // 发送上传命令、文件名和文件大小

        socket.write(request);
        socket.write(file.readAll());  // 发送文件内容
        socket.waitForBytesWritten();  // 等待写入完成
    }
    socket.close();  // 关闭连接
}

void Widget::requestFileList(const QString &serverAddress, quint16 serverPort) {
    QTcpSocket socket;
    socket.connectToHost(serverAddress, serverPort);  // 连接到服务器
    if (socket.waitForConnected()) {  // 等待连接成功
        QByteArray request;
        QDataStream out(&request, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_5_12);
        out << QString("LIST_FILES");  // 发送请求文件列表的命令

        socket.write(request);
        socket.waitForBytesWritten();  // 等待写入完成

        if (socket.waitForReadyRead()) {  // 等待服务器响应
            QByteArray response = socket.readAll();
            QDataStream in(&response, QIODevice::ReadOnly);
            in.setVersion(QDataStream::Qt_5_12);
            QStringList fileList;
            in >> fileList;  // 读取服务器返回的文件列表
            updateFileListView(fileList);  // 更新文件列表视图
        }
    }
    socket.close();  // 关闭连接
}

void Widget::downloadFileFromServer(const QString &serverAddress, quint16 serverPort, const QString &fileName, const QString &savePath) {
    QTcpSocket socket;
    socket.connectToHost(serverAddress, serverPort);  // 连接到服务器
    if (socket.waitForConnected()) {  // 等待连接成功
        QByteArray request;
        QDataStream out(&request, QIODevice::WriteOnly);
        out.setVersion(QDataStream::Qt_5_12);
        out << QString("DOWNLOAD") << fileName;  // 发送下载文件的命令和文件名

        socket.write(request);
        socket.waitForBytesWritten();  // 等待写入完成

        if (socket.waitForReadyRead()) {  // 等待服务器响应
            QByteArray response = socket.readAll();
            QDataStream in(&response, QIODevice::ReadOnly);
            in.setVersion(QDataStream::Qt_5_12);

            QString receivedFileName;
            QByteArray fileData;
            in >> receivedFileName >> fileData;  // 读取文件名和文件内容

            QFile file(savePath + "/" + receivedFileName);
            if (file.open(QIODevice::WriteOnly)) {  // 打开文件进行写入
                file.write(fileData);  // 将文件内容写入磁盘
                file.close();
            }
        }
    }
    socket.close();  // 关闭连接
}

void Widget::updateFileListView(const QStringList &fileList) {
    model->clear();
    model->setHorizontalHeaderLabels({"文件名"});
    for (const QString &fileName : fileList) {
        QList<QStandardItem *> row;
        row << new QStandardItem(fileName);
        model->appendRow(row);
    }
}
